home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / HardwareProjects / VideoText.lha / VideoText4.2 / source / bildschirm.p next >
Encoding:
Text File  |  1995-06-26  |  17.6 KB  |  571 lines

  1. UNIT bildschirm; {$project vt }
  2. { Bildschirmausgaben zum Programm VideoText }
  3.  
  4. INTERFACE; FROM vt USES pagelist,decode,cct,sys;
  5.  
  6. CONST colht=15;
  7. VAR jobcursor: Boolean;   { >Markierung in der Job- oder in der Seitenliste? }
  8.     incomplete: Boolean;  { Seitenaufbau unterbrochen? }
  9.     concealed: Boolean;   { verdeckte Zeichen wirklich verdeckt? }
  10.  
  11. PROCEDURE cursoroff;
  12. PROCEDURE cursoron;
  13. PROCEDURE mainline;
  14. FUNCTION ja_nein: Boolean;
  15. PROCEDURE mark_queue(really: Boolean);
  16. PROCEDURE redraw_queue(job: Integer);
  17. PROCEDURE space_in_queue;
  18. FUNCTION pos_from_queue(x,y: Integer): Integer;
  19. PROCEDURE mark_list(really: Boolean);
  20. PROCEDURE redraw_list;
  21. PROCEDURE update_list(start: p_onepage; delta: Integer);
  22. FUNCTION page_from_list(x,y: Integer): p_onepage;
  23. PROCEDURE fileinfo;
  24. PROCEDURE test(active: Boolean);
  25. PROCEDURE writepage(seite: p_onepage, verdeckt: Boolean);
  26. FUNCTION number_from_page(x,y: Integer): Integer;
  27. PROCEDURE redraw_all;
  28. FUNCTION click_action(x,y: Integer): Char;
  29.  
  30. { ---------------------------------------------------------------------- }
  31.  
  32. IMPLEMENTATION;
  33.  
  34. {$opt q,s+,i+ } { keine Laufzeitprüfungen außer Stack und Feldindizes }
  35.  
  36. CONST head=7; tail=6;  { Aufteilung der Warteschlange }
  37.       sp_maxdisp=15;
  38.  
  39. VAR listoffset: Integer;
  40.     fix1,fix2,fix3: Integer; { fileinfo-x-Positionen }
  41.  
  42. PROCEDURE cursoroff;
  43. BEGIN
  44.   Write(#155'0 p');  { Cursor unsichtbar }
  45. END;
  46.  
  47. PROCEDURE cursoron;
  48. BEGIN
  49.   Write(#155' p');  { Cursor wieder sichtbar }
  50. END;
  51.  
  52. PROCEDURE mainline;
  53. BEGIN
  54.   GotoXY(1,24); Write(#155'0m',Copy(blank40,1,39));
  55.   GotoXY(1,24);
  56. END;
  57.  
  58. FUNCTION ja_nein{: Boolean};
  59. VAR ch: Char;
  60. BEGIN
  61.   cursoron;
  62.   Write(' (J/N)?  ');
  63.   REPEAT
  64.     Delay(2); Write(#8' '#8);
  65.     ch := waitkey;
  66.     IF (Ord(ch) MOD 128)>31 THEN Write(ch) ELSE Write(' ');
  67.   UNTIL ch IN ['j', 'J', 'n', 'N']
  68.   ja_nein := ch IN ['j', 'J'];
  69.   cursoroff;
  70. END;
  71.  
  72. PROCEDURE mark_queue{(really: Boolean)};
  73. { Gibt die Position des Job-Markers <thisjob> als '>' am Bildschirm aus, }
  74. { <thisjob> kann Werte von <maxactive>-1 bis -<queued> annehmen. }
  75. { Für <really>=FALSE wird stattdessen ' ' ausgegeben. }
  76. CONST x0=1; y0=1;
  77. VAR y,j: Integer;
  78.     special: Boolean;
  79. BEGIN
  80.   special := False;
  81.   y := y0 + maxactive - thisjob;
  82.   IF thisjob<0 THEN BEGIN
  83.     y := y + 2;
  84.     IF NOT fifo THEN y := y + 1;
  85.     IF (queued>=colht) AND (-thisjob>head) THEN BEGIN
  86.       { unvollständige Anzeige der Schlange }
  87.       IF -thisjob>queued-tail THEN
  88.         y := y + colht-1 - queued { zeigt auf hinteres Ende }
  89.       ELSE BEGIN
  90.         special := True;
  91.         y := y + thisjob + head + 1; { zeigt auf die '...' }
  92.         j := (firstinq - thisjob - 2) MOD qlen + 1;
  93.       END;
  94.     END;
  95.   END;
  96.   GotoXY(x0,y); Write(#155'0m');
  97.   IF really THEN Write('>') ELSE Write(' ');
  98.   IF special THEN BEGIN
  99.     Write('(',hexstr(queue[j].pg,0),')');
  100.   END;
  101. END;
  102.  
  103. PROCEDURE redraw_queue{(job: Integer)};
  104. { Gibt für job<0 die aktuelle Belegung der Warteschlange und der aktiven Jobs }
  105. { am Bildschirm aus, sonst wird nur der Job mit der angegebenen Nummer neu }
  106. { ausgegeben: interessant ist dabei vor allem der Status der eingelesenen }
  107. { Unterseiten. }
  108. CONST x0=1; y0=1;
  109. VAR i,j,y,max: Integer;
  110. BEGIN
  111.   GotoXY(x0,y0); Write(#155'0m Seitensuche:');
  112.   FOR j := 0 TO maxactive-1 DO
  113.     IF (job<0) OR (j=job) THEN WITH activejobs[j] DO BEGIN
  114.       GotoXY(x0,maxactive+y0-j);
  115.       Write(Copy(blank40,1,25)); { nicht das Testfeld überschreiben! }
  116.       GotoXY(x0+1,maxactive+y0-j);
  117.       IF pg=0 THEN Write('---')
  118.       ELSE BEGIN
  119.         Write(hexstr(pg,0));
  120.         CASE sp OF
  121.           -3: Write('/!');
  122.           -2: Write('/.');
  123.           -1: Write('/*');
  124.            0: ;
  125.           OTHERWISE Write('/',hexstr(sp,0));
  126.         END;
  127.         Write('  ');
  128.         IF sp_check[0] THEN Write('+');
  129.         IF sp_max>0 THEN     { echte Unterseiten eingetroffen }
  130.           IF sp<>0 THEN       { zu einer Einzelanforderung? }
  131.             Write('+')
  132.           ELSE BEGIN
  133.             max := bcd(sp_max); IF max>sp_maxdisp THEN max := sp_maxdisp-2;
  134.             Write('(');
  135.             FOR i := 1 TO max DO
  136.               IF sp_check[i] THEN Write('+') ELSE Write('-');
  137.             IF bcd(sp_max)>max THEN Write('...') ELSE Write(')');
  138.           END;
  139.       END;
  140.     END;
  141.   GotoXY(x0,y0+2+maxactive); Write(' Jobs:');
  142.   IF job<0 THEN BEGIN
  143.     y := y0 + 3 + maxactive;
  144.     IF fifo THEN y := y + colht - 1;
  145.     GotoXY(x0,y); Write('         ');
  146.     FOR j := 1 TO colht-1 DO BEGIN
  147.       y := j+y0+2+maxactive; IF NOT fifo THEN y := y + 1;
  148.       GotoXY(x0,y); Write('         ');
  149.       IF j<=queued THEN BEGIN
  150.         GotoXY(x0+1,y);
  151.         i := (firstinq + j - 2) MOD qlen + 1;
  152.         IF (queued>=colht) AND (j>head) THEN
  153.           i := (firstinq + queued + j - colht - 1) MOD qlen + 1;
  154.         IF (queued>=colht) AND (j=head+1) THEN
  155.           Write('...')
  156.         ELSE WITH queue[i] DO BEGIN
  157.           Write(hexstr(pg,0));
  158.           CASE sp OF
  159.             -3: Write('/!');
  160.             -2: Write('/.');
  161.             -1: Write('/*');
  162.              0: ;
  163.             OTHERWISE Write('/',hexstr(sp,0));
  164.           END;
  165.         END;
  166.       END;
  167.     END; { Ende FOR-Schleife }
  168.   END;
  169.   IF jobcursor THEN mark_queue(True);
  170. END;
  171.  
  172. PROCEDURE space_in_queue;
  173. { den für Eingaben reservierten Platz in der Warteschlange ansteuern }
  174. CONST x0=1; y0=1;
  175. BEGIN
  176.   IF NOT fifo THEN
  177.     GotoXY(x0+1,y0+3+maxactive)
  178.   ELSE IF queued<colht THEN
  179.     GotoXY(x0+1,queued+y0+3+maxactive)
  180.   ELSE
  181.     GotoXY(x0+1,colht+y0+2+maxactive);
  182.   Write(#155'0m');
  183. END;
  184.  
  185. FUNCTION pos_from_queue{(x,y: Integer): Integer};
  186. { wurde auf eine Nummer in der Warteschlange geklickt? }
  187. CONST x0=1; y0=1;
  188. BEGIN
  189.   pos_from_queue := maxactive;  { unmöglicher Wert }
  190.   IF (x<x0) OR (x>x0+8) THEN Exit;
  191.   IF (y>y0) AND (y<=y0+maxactive) THEN
  192.     pos_from_queue := maxactive + y0 - y { Position in der Seitensuche }
  193.   ELSE BEGIN
  194.     y := y - y0 - maxactive - 2; IF NOT fifo THEN Dec(y);
  195.     IF (y>0) AND (y<colht) AND(y<=queued) THEN
  196.       IF (queued<colht) OR (y<=head) THEN
  197.         pos_from_queue := -y
  198.       ELSE
  199.         pos_from_queue := -(y-colht+queued+1);
  200.   END;
  201. END;
  202.  
  203. { Der Ärger mit der Seitenliste ... }
  204. CONST cols=3; colw=9; lspc='         '; { 9 Spaces }
  205.       x0=10; y0=3+maxactive;
  206.  
  207. FUNCTION adjust_offset: Integer;
  208. { Da die Seitenliste meist nicht ganz auf den Bildschirm paßt, gibt ein }
  209. { Offset an, ab wo sie sichtbar ist, dieser <listoffset> wird hier neu }
  210. { berechnet. Der Rückgabewert sagt, um wieviele Spalten die Liste (falls }
  211. { bereits angezeigt) verschoben werden muß. (>0: rechts kommen Spalten dazu) }
  212. VAR nr,delta: Integer;
  213.     hilf: p_onepage;
  214. BEGIN
  215.   { Herausfinden, die wievielte Seite in der Liste <thispage> ist: }
  216.   hilf := root; nr := 0;
  217.   WHILE (hilf<>Nil) AND (hilf<>thispage) DO BEGIN
  218.     hilf := hilf^.next; Inc(nr);  END;
  219.   delta := 0;
  220.   WHILE nr<listoffset DO BEGIN
  221.     listoffset := listoffset-colht; Dec(delta);  END;
  222.   WHILE nr-listoffset>=cols*colht DO BEGIN
  223.     listoffset := listoffset+colht; Inc(delta);  END;
  224.   adjust_offset := delta;
  225. END;
  226.  
  227. PROCEDURE listentry(ch: Char; seite: p_onepage; nr: Integer);
  228. { Einen Listeneintrag erzeugen, von dem seine Nummer im sichtbaren Bereich }
  229. { der Liste bekannt ist. <ch> ist normalerweise '?', oder ' ', '>' um eins }
  230. { der beiden Zeichen zu erzwingen. }
  231. VAR x,y: Integer;
  232. BEGIN
  233.   x := x0+colw*(nr DIV colht); y := y0+1+nr MOD colht;
  234.   GotoXY(x,y);
  235.   IF ch='?' THEN BEGIN
  236.     Write(#155'0m',lspc); GotoXY(x,y);
  237.     IF NOT jobcursor AND (seite=thispage) THEN ch :='>' ELSE ch := ' ';
  238.   END;
  239.   IF seite<>Nil THEN
  240.     Write(ch,hexstr(seite^.pg,0),'/',hexstr(seite^.sp,0));
  241. END;
  242.  
  243. PROCEDURE redraw_column(col: Integer);
  244. { gibt eine Spalte der Seitenliste aus }
  245. VAR i: Integer;
  246.     hilf: p_onepage;
  247. BEGIN
  248.   hilf := root;
  249.   FOR i := 1 TO listoffset+(col-1)*colht DO
  250.     IF hilf<>Nil THEN hilf := hilf^.next;
  251.   FOR i := 1 TO colht DO BEGIN
  252.     listentry('?',hilf,(i-1)+(col-1)*colht);
  253.     IF hilf<>Nil THEN hilf := hilf^.next;
  254.   END;
  255. END;
  256.  
  257. PROCEDURE mark_list{(really: Boolean)};
  258. { Gibt die Position des Seiten-Markers <thispage> am Bildschirm aus, für }
  259. { <really>=FALSE wird die Markierung dagegen aufgehoben. }
  260. { Scrollt die Liste auch weiter, falls nötig. }
  261. VAR nr,i: Integer;
  262.     dx: Integer;
  263.     hilf: p_onepage;
  264. BEGIN
  265.   { scrollen? }
  266.   dx := adjust_offset;
  267.   FOR i := cols DOWNTO 1 DO BEGIN
  268.     IF dx>=i THEN  scroll_text(y0+1,y0+colht,x0,x0+cols*colw-1,0,colw);
  269.     IF dx<=-i THEN  scroll_text(y0+1,y0+colht,x0,x0+cols*colw-1,0,-colw);
  270.   END;
  271.   FOR i := 1 TO cols DO
  272.     IF (i+dx>cols) OR (i+dx<1) THEN
  273.       redraw_column(i);
  274.   { Herausfinden, die wievielte Seite in der Liste <thispage> ist: }
  275.   hilf := root; nr := 0;
  276.   WHILE (hilf<>Nil) AND (hilf<>thispage) DO BEGIN
  277.     hilf := hilf^.next; Inc(nr);
  278.   END;
  279.   nr := nr-listoffset;
  280.   IF really THEN
  281.     listentry('>',thispage,nr) ELSE listentry(' ',thispage,nr);
  282. END;
  283.  
  284. PROCEDURE redraw_list;
  285. { aktualisiert die gesamte Seitenliste }
  286. VAR i: Integer;
  287.     hilf: p_onepage;
  288. BEGIN
  289.   IF adjust_offset<>0 THEN; { Wert ist egal }
  290.   GotoXY(x0,y0); Write(#155,'0m Im Speicher:');
  291.   hilf := root;
  292.   FOR i := 1 TO listoffset DO
  293.     IF hilf<>Nil THEN hilf := hilf^.next;
  294.   FOR i := 0 TO cols*colht-1 DO BEGIN
  295.     listentry('?',hilf,i);
  296.     IF hilf<>Nil THEN hilf := hilf^.next;
  297.   END;
  298. END;
  299.  
  300. PROCEDURE redraw_rows(rows: Integer);
  301. { gibt die ersten <rows> bzw. die letzten <-rows> Zeilen der Seitenliste }
  302. { aus, nicht ganz trivial }
  303. VAR i,j: Integer;
  304.     hilf: p_onepage;
  305. BEGIN
  306.   hilf := root;
  307.   FOR i := 1 TO listoffset DO
  308.     IF hilf<>Nil THEN hilf := hilf^.next;
  309.   FOR i := 1 TO cols DO
  310.     FOR j := 1 TO colht DO BEGIN
  311.     IF (j<=rows) OR (j>colht+rows) THEN
  312.       listentry('?',hilf,(j-1)+(i-1)*colht);
  313.     IF hilf<>Nil THEN hilf := hilf^.next;
  314.   END;
  315. END;
  316.  
  317. PROCEDURE update_list{(start: p_onepage; delta: Integer)};
  318. { Es wurden Seiten in die Liste eingefügt (delta>0) bzw. entfernt (delta<0). }
  319. { <start> ist die erste Seite, die sich dadurch geändert hat. }
  320. VAR i,nr: Integer;
  321.     hilf: p_onepage;
  322. BEGIN
  323.   { Herausfinden, wo auf dem Bildschirm die bezeichnete Seite ist }
  324.   hilf := root; nr := 0;
  325.   WHILE (hilf<>Nil) AND (hilf<>start) DO BEGIN
  326.     hilf := hilf^.next; Inc(nr);
  327.   END;
  328.   nr := nr-listoffset;
  329.   { ein paar Spalten komplett scrollen, eine nur zum Teil }
  330.   FOR i := 1 TO cols DO BEGIN
  331.     IF (i-1)*colht>=nr THEN
  332.       scroll_text(y0+1,y0+colht,x0+(i-1)*colw,x0+i*colw-1,-delta,0)
  333.     ELSE IF i*colht>=nr+Abs(delta) THEN
  334.       scroll_text(y0+1+nr MOD colht,y0+colht,x0+(i-1)*colw,x0+i*colw-1,-delta,0)
  335.   END;
  336.   hilf := start;
  337.   FOR i := 0 TO delta-1 DO BEGIN
  338.     IF (nr+i<cols*colht) AND (nr+i>=0) THEN listentry('?',hilf,nr+i);
  339.     IF hilf<>Nil THEN hilf := hilf^.next;
  340.   END;
  341.   redraw_rows(delta);
  342.   { '>' neu setzten, hat evtl. sogar den Bildschirm verlassen: }
  343.   mark_list(NOT jobcursor);
  344. END;
  345.  
  346. FUNCTION page_from_list{(x,y: Integer): p_onepage};
  347. { zu einer angeklickten Zeichenposition die Seite herausfinden }
  348. VAR nr: Integer;
  349.     hilf: p_onepage;
  350. BEGIN
  351.   page_from_list := Nil;
  352.   IF (y IN [y0+1..y0+colht]) AND (x IN [x0-2..x0+cols*colw+2]) THEN BEGIN
  353.     nr := listoffset + y - (y0+1) + colht*(Round((x-x0)/colw+0.5)-1);
  354.     hilf := root;
  355.     IF hilf<>Nil THEN
  356.       WHILE (hilf^.next<>Nil) AND (nr>0) DO BEGIN
  357.         hilf := hilf^.next; Dec(nr);
  358.       END;
  359.     IF nr=0 THEN page_from_list := hilf;
  360.   END ELSE IF (y=y0) AND (x IN [x0..x0+12]) THEN  { Überschrift angeklickt }
  361.     page_from_list := root;
  362. END;
  363.  
  364. PROCEDURE fileinfo;
  365. CONST x0=1; y0=26;
  366. BEGIN
  367.   GotoXY(x0,y0);
  368.   Write(#155'0mDatei ('); fix1 := x0 + 7;
  369.   fix2 := fix1 + 4;
  370.   IF asciifile THEN BEGIN  Write('ASCII, '); fix2 := fix2 + 3; END
  371.     ELSE Write('VT, ');
  372.   fix3 := fix2 + 11;
  373.   IF overwrite THEN BEGIN  Write('}berschr.): '); fix3 := fix3 + 1; END
  374.     ELSE  Write('anf}gend): ');
  375.   Write(#155'2m',outputname);
  376.   IF withicon THEN Write(#155'0m, mit Icon');
  377.   ClrEoL;
  378. END;
  379.  
  380. PROCEDURE test{(active: Boolean)};
  381. { Decodertest, sollte aus einer Schleife heraus aufgerufen werden. }
  382. { für active=false wird ein leeres Testfeld erzeugt. }
  383. CONST x0=26; y0=1;
  384. VAR stat: Byte;
  385.     i: Integer;
  386.     zeit: str80;
  387.     ch: char;
  388.     tag,min,tic: Long;
  389. PROCEDURE zweistellig(x: Integer);  BEGIN  Write(x DIV 10, x MOD 10);  END;
  390. BEGIN
  391.   GotoXY(x0,y0);
  392.   Write(#155'0mStatus:');
  393.   IF NOT active THEN BEGIN
  394.     FOR stat := 1 TO 5 DO BEGIN
  395.       GotoXY(x0,y0+stat); Write('             ');  { 13 Spaces }
  396.     END;
  397.     Write(#155,'2m');
  398.   END;
  399.   GotoXY(x0,y0+1); Write('Bus:');
  400.   GotoXY(x0+5,y0+1); Write('AV:');
  401.   GotoXY(x0+5,y0+2); Write('VT:');
  402.   GotoXY(x0,y0+3); Write(' VT:');
  403.   GotoXY(x0,y0+4); Write('Sys:');
  404.   IF active THEN BEGIN
  405.     Write(#155,'2m');
  406.     stat := VTstat;
  407.     GotoXY(x0,y0+2);
  408.     IF i2c_status=0 THEN
  409.       Write('OK  ') ELSE Write('Err',i2c_status);
  410.     FOR i := 1 TO 2 DO BEGIN
  411.       GotoXY(x0+9,y0+i);
  412.       IF i2c_status=0 THEN
  413.         IF (stat AND i)<>0 THEN Write('ja  ')  ELSE  Write('nein')
  414.       ELSE
  415.         Write('    ')
  416.     END;
  417.     { Zeit aus dem VT-Seitenspeicher abfragen: }
  418.     gettime(aktspeicher,zeit);
  419.     GotoXY(x0+5,y0+3); Write(zeit);
  420.     { zum Vergleich: Amiga-Zeit }
  421.     telltime(tag,min,tic);
  422.     GotoXY(x0+5,y0+4);
  423.     zweistellig(min DIV 60); Write(':');
  424.     zweistellig(min MOD 60); Write(':');
  425.     zweistellig(tic DIV 50);
  426.   END;
  427.   Write(#155'0m');
  428. END;
  429.  
  430. PROCEDURE writepage{(seite: p_onepage, verdeckt: Boolean)};
  431. { Seite am Bildschirm ausgeben }
  432. CONST xoff = 40;
  433. VAR zeile,i,j,j0: Integer;
  434.     farbe,farbe0: Word;
  435.     out: bigstring;
  436.     x: Byte;
  437.     s,attrib: str80;
  438.     dblheight,rastergfx,special: Boolean;
  439.     normal: String[10];
  440. BEGIN
  441.   visblpage := seite;
  442.   concealed := verdeckt;
  443.   normal := #155'0;3'+colperms[7]+';4'+colperms[0]+'m'; { weiß auf schwarz }
  444.   incomplete := True;
  445.   dblheight := False; rastergfx := False;
  446.   IF seite<>Nil THEN seite^.chars[0] := 2;  { Seitennummer zunächst grün }
  447.   for i := 0 to 24 do begin
  448.     zeile := i MOD 24;
  449.     IF i=24 THEN BEGIN
  450.       { 1. Zeile nochmal, mit weißer Seitennummer: }
  451.       IF seite<>Nil THEN seite^.chars[0] := 7;
  452.       dblheight := False;
  453.       incomplete := False;   { Seite komplett }
  454.     END;
  455.     IF dblheight THEN
  456.       { auf eine doppelthohe Zeile folgt nur eine leere Zeile }
  457.       dblheight := False
  458.     ELSE BEGIN
  459.       { normale Zeile ausgeben }
  460.       IF seite<>Nil THEN
  461.         decode_line(seite, zeile, verdeckt, out, attrib, dblheight, rastergfx)
  462.       ELSE
  463.         out := blank40;
  464.       GotoXY(xoff,zeile+1); Write(normal,out,normal,' ');
  465.       IF rastergfx THEN BEGIN  { Zeile, die gerasterte Grafikzeichen enthält }
  466.         special := False; farbe := 0;
  467.         FOR j := 0 TO 39 DO BEGIN  { zu rasternde Abschnitte suchen }
  468.           farbe0 := farbe; farbe := Ord(attrib[j+1]);
  469.           IF (farbe<>farbe0) AND special THEN BEGIN
  470.             raster_line(zeile+1,xoff+j0,xoff+j-1,farbe0 AND 7);
  471.             j0 := j; special := (farbe AND 16<>0);
  472.           END;
  473.           IF (farbe AND 16<>0) AND NOT special THEN BEGIN
  474.             j0 := j; special := True;
  475.           END;
  476.         END;
  477.         IF special THEN
  478.           raster_line(zeile+1,xoff+j0,xoff+39,farbe0 AND 7);
  479.       END;
  480.       IF zeile=23 THEN dblheight := False; { unterste Zeile nie doppelthoch! }
  481.       IF dblheight THEN BEGIN   { Handhabung doppelthoher Zeilen }
  482.         special := False;
  483.         FOR j := 1 TO Length(out) DO BEGIN   { alles außer den ANSI-Codes }
  484.           { entfernen -> erzeugt Kopie der Hintergrundfarben der Zeile }
  485.           IF out[j] = #155 THEN special := True;
  486.           IF NOT special THEN out[j] := ' ';
  487.           IF out[j] = 'm' THEN special := False;
  488.         END;
  489.         GotoXY(xoff,zeile+2); Write(normal,out,normal,' ');
  490.         special := False;
  491.         FOR j := 0 TO 39 DO   { doppelthohe Abschnitte suchen }
  492.           CASE seite^.chars[40*zeile+j] OF
  493.             13: BEGIN j0 := j; special := True; END;
  494.             12: IF special THEN BEGIN
  495.                 stretch_line(zeile+1,xoff+j0,xoff+j); special := False;
  496.               END;
  497.             OTHERWISE;
  498.           END;
  499.         IF special THEN
  500.           stretch_line(zeile+1,xoff+j0,79);
  501.       END;
  502.     END;
  503.     lastkey := readkey; { Taste: Abbruch und Rückmeldung ans HP }
  504.     intui_events;
  505.     IF (lastkey<>chr(0)) OR stop THEN
  506.       Exit;
  507.   END;
  508. END;
  509.  
  510. FUNCTION number_from_page{(x,y: Integer): Integer};
  511. { versucht zu einer angeklickten Bildschirmposition herauszufinden, auf }
  512. { was für eine Nummer geklickt wurde }
  513. VAR i,j,j0,n,m: Integer;
  514.     ok: Boolean;
  515. CONST xoff = 40;
  516. BEGIN
  517.   n := -1;
  518.   IF (x IN [xoff..xoff+39]) AND (y IN [1..24]) AND (visblpage<>Nil) THEN BEGIN
  519.     i := 40*(y-1);
  520.     ok := True; j0 := x-xoff;
  521.     FOR j := x-xoff DOWNTO 0 DO BEGIN
  522.       IF NOT (visblpage^.chars[i+j] IN [48..57]) THEN ok := False;
  523.       IF ok THEN j0 := j;
  524.     END;
  525.     ok := True; n := 0; m := 0;
  526.     FOR j := j0 TO 39 DO BEGIN
  527.       IF NOT (visblpage^.chars[i+j] IN [48..57]) THEN ok := False;
  528.       IF ok THEN BEGIN
  529.         n := (n SHL 4) + visblpage^.chars[i+j]-48; Inc(m);
  530.       END;
  531.     END;
  532.     IF m=0 THEN n := -1;  { keine Ziffern gefunden }
  533.   END;
  534.   number_from_page := n;
  535. END;
  536.  
  537. PROCEDURE redraw_all;
  538. { kompletter Neuaufbau des Bildschirms, inklusive clrscr }
  539. BEGIN
  540.   ClrScr;
  541.   writepage(thispage,True); test(False);
  542.   redraw_queue(-1); redraw_list; fileinfo;
  543. END;
  544.  
  545. FUNCTION click_action{(x,y: Integer): Char};
  546. { Ein paar bestimmte Sachen, die man anklicken kann }
  547. BEGIN
  548.   click_action := ' ';
  549.   IF (y=1) AND (x IN [26..32]) THEN click_action := 'T'; { "Status" }
  550.   IF (y=1) AND (x IN [2..13]) THEN click_action := 'S'; { "Seitensuche" }
  551.   IF (y=7) AND (x IN [2..6]) THEN click_action := 'J'; { "Jobs" }
  552.   IF (y=26) THEN BEGIN
  553.     IF x IN [1..fix1-3] THEN click_action := 'D'; { Dateiname }
  554.     IF x IN [fix1..fix2-3] THEN click_action := 'F'; { Format }
  555.     IF x IN [fix2..fix3-4] THEN click_action := 'M'; { Modus }
  556.     IF x IN [fix3..80] THEN click_action := 'I'; { Icon? }
  557.   END;
  558.   IF (x>=40) THEN CASE y OF
  559.       1..8: click_action := '-'; { oberes Seitendrittel }
  560.       17..24: click_action := '+'; { unteres Seitendrittel }
  561.       OTHERWISE;
  562.     END;
  563. END;
  564.  
  565. BEGIN { Initialisierungsteil }
  566.   listoffset := 0;
  567.   jobcursor := False;
  568.   incomplete := False;
  569.   concealed := True;
  570. END.
  571.